// Promise 最重要的核心就是解决 1.异步并发 2.回调地狱

const enum STATIS {
    pending = "PENDING",
    fulfilled = "FULFILLED",
    rejected = "REJECTED"
}

class myPromise {
    status: STATIS
    value: any
    reason: any
    onFulilledCallbaks:Array<Function>
    onRejectedCallbaks:Array<Function>
    constructor(executor) {
        this.status = STATIS.pending; // 当前默认状态
        this.value = undefined; // 成功原因
        this.reason = undefined; // 失败原因

        /* ----*/
        this.onFulilledCallbaks= [] 
        this.onRejectedCallbaks= []

        // 成功方法
        const resolve = (value?) => {

            if (this.status === STATIS.pending) {
                this.status = STATIS.fulfilled
                this.value = value // 成功结果
                // 执行存储成功函数
                this.onRejectedCallbaks.forEach(item=> item())
            }

        }

        //失败的方法
        const reject = (reason?) => {
            if (this.status === STATIS.pending) {
                this.status = STATIS.rejected
                this.reason = reason  // 失败结果
                  // 执行存储失败函数
                this.onFulilledCallbaks.forEach(item=>item())
            }
        }
        // 当代码失败的时候会调用 reject
        try {
            executor(resolve, reject)
        } catch (e) {
            reject(e)
        }
    }
    // 实现then方法
    then(onFulilled,onRejected){
        // 成功
      if(this.status == STATIS.fulfilled){
        onFulilled(this.value)
      }

       // 失败
      if(this.status == STATIS.rejected){
        onRejected(this.reason)
      }
      /*
        setTimeout(()=>{
        reject('no ok')
         },1000)
      当时status 状态是初始化状态时候,应该把onFulilled,onRejected
         回调函数存储起来，等失败或者成功在执行
      */ 
      if(this.status == STATIS.pending){
           // 成功回调函数存储
           this.onFulilledCallbaks.push(()=>{ // 这样用切片思想
            // todo... 额外的逻辑
            onFulilled(this.value)
           }) 
            // 失败回调 
           this.onRejectedCallbaks.push(()=>{
            onFulilled(this.value)
           })
      }
    }

    
}



const p = new myPromise((resolve, reject) => {
    // resolve('ok')
    
    setTimeout(()=>{
        resolve('ok')
    },1000)

})

p.then((res: any) => {
 console.log( 'success',res)
},(err: any)=>{
    console.log('faild',err)
})
p.then((res: any) => {
    console.log( 'success2',res)
   },(err: any)=>{
       console.log('faild2',err)
   })

export { }